home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Hardware / PCI Driver Development Kit / • Tools / Utility / DisplayNameRegistry 950412 / Src / EnumerateNameRegistry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-27  |  9.0 KB  |  310 lines  |  [TEXT/MPCC]

  1. /*                                EnumerateNameRegistry.c                                */
  2. /*
  3.  * EnumerateNameRegistry.c
  4.  *
  5.  * Store the Name Registry into a two-level TwistDown list. The primary list has
  6.  * the path name and property name concatenated. Each element has a secondary list
  7.  * containing the element data. For example, suppose that the registry has the form:
  8.  *        Path A
  9.  *            First Property
  10.  *                First Property's Value
  11.  *            Second Property
  12.  *                Second Property's Value
  13.  *        Path B
  14.  *            First Property
  15.  *                First Property's Value
  16.  *            Second Property
  17.  *                Second Property's Value
  18.  * The resulting registry (REG) list will look like this:
  19.  *        Path A : First Property
  20.  *            First Property's Value
  21.  *        Path A : Second Property
  22.  *            Second Property's Value
  23.  *        Path B : First Property
  24.  *            First Property's Value
  25.  *        Path B : Second Property
  26.  *            Second Property's Value
  27.  * If this is then sorted on property (as opposed to the default of path), we get:
  28.  *        First Property
  29.  *            Path A
  30.  *                First Property's Value
  31.  *            Path B
  32.  *                First Property's Value
  33.  *        Second Property
  34.  *            Path A
  35.  *                First Property's Value
  36.  *            Path B
  37.  *                First Property's Value
  38.  */
  39. #include "DisplayNameRegistry.h"
  40.  
  41. void                        EnumeratePropertiesForThisName(
  42.         register BrowserPtr        browserPtr,
  43.         RegEntryID                *entryID,
  44.         UInt32                    regEntrySequence,
  45.         const RegCStrPathName    *pathName
  46.     );
  47. OSErr                        StoreThisDatum(
  48.         register BrowserPtr        browserPtr,
  49.         UInt32                    regEntrySequence,
  50.         const RegCStrPathName    *pathName,
  51.         const RegPropertyNameBuf foundProperty,
  52.         RegPropertyModifiers     propertyModifiers,
  53.         RegPropertyValueSize    propertySize,
  54.         const void                *propertyValue
  55.     );
  56. Boolean                        CheckForUserAbort(void);
  57.  
  58. /*
  59.  * This is adapted from the sample in the 8/3/94 PCI Drivers draft. Enumerate all
  60.  * paths and all propeties for each path. Store the entire collection in a sibling set
  61.  * stored in the Browser Record. The list will be then sorted and broken into primary
  62.  * and secondary sort keys according to the user's menu selection. On exit,
  63.  * BROWSER.registrySiblingSet.firstElement is the head of the list.
  64.  */
  65. void
  66. EnumerateNameRegistry(
  67.         BrowserPtr                browserPtr
  68.     )
  69. {
  70.         OSErr                    status;
  71.         RegEntryIter            cookie;
  72.         Boolean                    done;
  73.         RegEntryIterationOp        op;
  74.         RegEntryID                entry;
  75.         RegCStrPathName            *pathName;
  76.         RegPathNameSize            pathNameSize;
  77.         UInt32                    regEntrySequence;
  78.         
  79.         NewTwistDownSiblingSet(®);
  80.         op = kRegIterContinue;
  81.         regEntrySequence = 0;
  82.         status = RegistryEntryIterateCreate(&cookie);
  83.         CheckError(status, "\pRegistryEntryIterateCreate");
  84.         if (status == noErr) {
  85.             done = FALSE;
  86.             while (status == noErr && done == FALSE) {
  87.                 if (CheckForUserAbort())
  88.                     break;
  89.                 status = RegistryEntryIterate(&cookie, op, &entry, &done);
  90.                 CheckError(status, "\pRegistryEntryIterate");
  91.                 if (status == noErr && done == FALSE) {
  92.                     pathName = NULL;
  93.                     status = RegistryEntryToPathSize(&entry, &pathNameSize);
  94.                     CheckError(status, "\pRegistryEntryToPathSize");
  95.                     if (status == noErr) {
  96.                         pathName = (RegCStrPathName *) NewPtr(pathNameSize);
  97.                         if (pathName == NULL)
  98.                             status = MemError();
  99.                     }
  100.                     if (status == noErr) {
  101.                         status = RegistryCStrEntryToPath(&entry, pathName, pathNameSize);
  102.                         CheckError(status, "\pRegistryCStrEntryToPath");
  103.                     }
  104.                     if (status == noErr) {
  105.                         ++regEntrySequence;        /* Increment before using            */
  106.                         EnumeratePropertiesForThisName(
  107.                             browserPtr, &entry, regEntrySequence, pathName);
  108.                     }
  109.                     if (pathName != NULL)
  110.                         DisposePtr((Ptr) pathName);
  111.                     RegistryEntryIDDispose(&entry);
  112.                 }
  113.             }
  114.             RegistryEntryIterateDispose(&cookie);
  115.         }
  116. }
  117.  
  118. /*
  119.  * EnumeratePropertiesForThisName finds all properties for the current path. It creates
  120.  * a new registry list element (path : property) and a sub-list for the property values.
  121.  */
  122. void
  123. EnumeratePropertiesForThisName(
  124.         register BrowserPtr        browserPtr,
  125.         RegEntryID                *entryID,
  126.         UInt32                    regEntrySequence,
  127.         const RegCStrPathName    *pathName
  128.     )
  129. {
  130.         OSErr                    status;
  131.         RegPropertyIter            cookie;
  132.         Boolean                    done;
  133.         RegPropertyNameBuf        foundProperty;
  134.         RegPropertyValueSize    propertySize;
  135.         RegPropertyModifiers     propertyModifiers;
  136.         void                    *propertyValue;
  137.  
  138.         status = RegistryPropertyIterateCreate(entryID, &cookie);
  139.         CheckError(status, "\pRegistryPropertyIterateCreate");
  140.         if (status == noErr) {
  141.             done = FALSE;
  142.             while (status == noErr && done == FALSE) {
  143.                 status = RegistryPropertyIterate(&cookie, foundProperty, &done);
  144.                 CheckError(status, "\pRegistryPropertyIterate");
  145.                 if (status == noErr && done == FALSE) {
  146.                     propertyValue = NULL;
  147.                     status = RegistryPropertyGetSize(
  148.                                 entryID, foundProperty, &propertySize);
  149.                     CheckError(status, "\pRegistryPropertyGetSize");
  150.                     if (status == noErr) {
  151.                         propertyValue = NewPtr(propertySize);
  152.                         if (propertyValue == NULL) {
  153.                             status = MemError();
  154.                             NonFatalError(status, "\pNo memory to store property");
  155.                         }
  156.                     }
  157.                     if (status == noErr) {
  158.                         status = RegistryPropertyGet(
  159.                                     entryID,
  160.                                     foundProperty,
  161.                                     propertyValue,
  162.                                     &propertySize
  163.                                 );
  164.                         CheckError(status, "\pRegistryPropertyGet");
  165.                     }
  166.                     if (status == noErr) {
  167.                         status = RegistryPropertyGetMod(
  168.                                     entryID,
  169.                                     foundProperty,
  170.                                     &propertyModifiers
  171.                                 );
  172.                         CheckError(status, "\pRegisteryPropertyGetMod");
  173.                     }
  174.                     if (status == noErr) {
  175.                         status = StoreThisDatum(
  176.                                     browserPtr,
  177.                                     regEntrySequence,
  178.                                     pathName,
  179.                                     foundProperty,
  180.                                     propertyModifiers,
  181.                                     propertySize,
  182.                                     propertyValue
  183.                                 );
  184.                         if (status != noErr)
  185.                             NonFatalError(status, "\pCould not store property");
  186.                     }
  187.                     if (propertyValue != NULL)
  188.                         DisposePtr((Ptr) propertyValue);
  189.                 }
  190.             }
  191.             RegistryPropertyIterateDispose(&cookie);
  192.         }
  193. }
  194.  
  195. /*
  196.  * StoreThisDatum stores a path : property : value in the list. Registry list elements
  197.  * are always locked in memory. The path + property is stored as two concatenated
  198.  * C-strings. This is the only routine that constructs a registry list element.
  199.  */
  200. OSErr
  201. StoreThisDatum(
  202.         register BrowserPtr        browserPtr,
  203.         UInt32                    regEntrySequence,
  204.         const RegCStrPathName    *pathName,
  205.         const RegPropertyNameBuf foundProperty,
  206.         RegPropertyModifiers     propertyModifiers,
  207.         RegPropertyValueSize    propertySize,
  208.         const void                *propertyValue
  209.     )
  210. {
  211.         OSErr                    status;
  212.         unsigned long            totalNameSize;
  213.         short                    pathNameSize;
  214.         short                    foundPropertySize;
  215. #define ELEM (**REG.thisElement)
  216.  
  217.         /*
  218.          * The name is stored as two concatenated C strings:
  219.          *    path EOS property EOS preceeded the binary sequence number.
  220.          */
  221.         pathNameSize = strlen(pathName);
  222.         foundPropertySize = strlen(foundProperty);
  223.         totalNameSize = sizeof regEntrySequence + pathNameSize + 1 + foundPropertySize + 1; 
  224.         status = MakeTwistDownSibling(®, 0, totalNameSize, NULL);
  225.         if (status == noErr) {
  226.             MoveHHi((Handle) REG.thisElement);
  227.             HLock((Handle) REG.thisElement);            /* Locked from now on        */
  228.             if ((propertyModifiers & kRegPropertyValueIsSavedToNVRAM) != 0)
  229.                 ELEM.flag |= kSavedInNVRAM;
  230.             if ((propertyModifiers & kRegPropertyValueIsSavedToDisk) != 0)
  231.                 ELEM.flag |= kSavedOnDisk;
  232.             BlockMoveData(
  233.                 ®EntrySequence,
  234.                 &ELEM.data[0],
  235.                 sizeof regEntrySequence
  236.             );
  237.             BlockMoveData(
  238.                 pathName,
  239.                 &ELEM.data[sizeof regEntrySequence],
  240.                 pathNameSize
  241.             );
  242.             /*
  243.              * Terminate the path name string.
  244.              */
  245.             ELEM.data[pathNameSize + sizeof regEntrySequence] = '\0';
  246.             BlockMoveData(
  247.                 foundProperty,
  248.                 &ELEM.data[sizeof regEntrySequence + pathNameSize + 1],
  249.                 foundPropertySize
  250.             );
  251.             ELEM.data[totalNameSize - 1] = '\0';        /* End of property string    */
  252.             if (propertySize > 0) {                        /* Property in sub-list        */
  253.                 /*
  254.                  * This will always create a sub-list. If the sub-list has a single
  255.                  * element, and it's short enough, the display module will scrunch
  256.                  * the secondary key and the data onto a single line of text.
  257.                  */
  258.                 ELEM.flag |= kHasTwistDown;
  259.                 ELEM.subElement = FormatThisProperty(
  260.                             foundProperty,
  261.                             propertySize,
  262.                             propertyValue
  263.                         );
  264.             }
  265.         }
  266.         return (status);
  267. #undef ELEM
  268. }
  269.  
  270. /*
  271.  * You must lock down the element before calling this routine. This is the only
  272.  * routine that unpacks a registry element. This function returns the registry
  273.  * entry sequence id that is needed to disambiguate between different entries
  274.  * with identical entry names.
  275.  */
  276. UInt32
  277. UnpackDataRecord(
  278.         const TwistDownPtr        thisElement,        /* Locked TwistDownHdl            */
  279.         char                    **pathNameCString,
  280.         char                    **foundPropertyCString
  281.     )
  282. {
  283. #define ELEM (*thisElement)
  284.         UInt32                    result;
  285.         
  286.         BlockMoveData(&ELEM.data[0], &result, sizeof result);
  287.         *pathNameCString = (char *) &ELEM.data[sizeof result];
  288.         *foundPropertyCString =
  289.             (char *) &ELEM.data[sizeof result + strlen(*pathNameCString) + 1];
  290.         return (result);
  291. #undef ELEM
  292. }
  293.  
  294. Boolean
  295. CheckForUserAbort(void)
  296. {
  297.         EventRecord                currentEvent;
  298.         Boolean                    result;
  299.  
  300.         EventAvail(everyEvent, ¤tEvent);
  301.         SpinCursor();
  302.         result = FALSE;
  303.         if ((currentEvent.what == keyDown || currentEvent.what == autoKey)
  304.          && (currentEvent.modifiers & cmdKey) != 0
  305.          && (currentEvent.message & keyCodeMask) == '.')
  306.              result = TRUE;
  307.         return (result);
  308. }
  309.  
  310.